#include "core/async_listener_impl.h"
#include "core/async_packet_socket_impl.h"

namespace vz {

AsyncListenerImpl::AsyncListenerImpl(AsyncSocket* socket)
  : socket_(socket) {
}


AsyncListenerImpl::~AsyncListenerImpl() {
}

AsyncListenerImpl::Ptr AsyncListenerImpl::SharedFromThis() {
  return AsyncListener::Ptr(this);
}

bool AsyncListenerImpl::Start(SocketAddress &address, int listen_backlog) {
  socket_->SignalReadEvent.connect(this,
                                   &AsyncListenerImpl::OnReadEvent);
  socket_->SignalCloseEvent.connect(this,
                                    &AsyncListenerImpl::OnCloseEvent);

  if (socket_->Bind(address) == SOCKET_ERROR) {
    LOG(LS_ERROR) << "bind socket failed!" << address.ToString();
    return false;
  }
  if (socket_->Listen(listen_backlog) == SOCKET_ERROR) {
    LOG(LS_ERROR) << "listen socket failed!" << address.ToString();
    return false;
  }

  return true;
}

void AsyncListenerImpl::OnReadEvent(AsyncSocket* async_socket) {
  ASSERT(async_socket == socket_);

  SocketAddress address;
  AsyncSocket* new_socket = socket_->Accept(&address);

  AsyncPacketSocket::Ptr packet_socket =
    new RefCountedObject<AsyncPacketSocketImpl>(new_socket);

  SignalAcceptEvent(SharedFromThis(), packet_socket);
}

void AsyncListenerImpl::OnCloseEvent(AsyncSocket* async_socket, int errcode) {
  ASSERT(async_socket == socket_);
  SignalCloseEvent(SharedFromThis(), errcode);
}

}  // namespace vz